<?php
/**
 * Created by PhpStorm.
 * User: zyh
 * Date: 2018/5/4
 * Time: 上午9:08
 */

namespace app\index\command;

use app\admin\model\Game;
use app\admin\model\Rewards;
use app\admin\model\System;
use app\admin\model\User;
use app\admin\model\Userhis;
use GatewayWorker\Lib\Gateway;
use think\Cache;
use think\console\Input;
use think\console\Output;
use think\Db;
use think\Exception;
use think\Session;

class Events
{

    /**
     * 当客户端连接时触发
     * 如果业务不需此回调可以删除onConnect
     *
     * @param int $client_id 连接id
     */
    public static function onConnect($client_id)
    {
        $init_msg = '{"type":"init","data":"' . $client_id . '"}';
//        Events::sendToClient($client_id, $init_msg);

        Events::sendToClient($client_id,$init_msg);
        Cache::set($client_id.'_ip',$_SERVER['REMOTE_ADDR']);
//        $output = new Output();;
//        $output->writeln(print_r($_SERVER, true));//"user $client_id logout"

    }

    /**
     * 当客户端发来消息时触发
     * @param int $client_id 连接id
     * @param mixed $message 具体消息
     * @throws \Exception
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function onMessage($client_id, $message)
    {
        $output = new Output();
//        $output->writeln('cache ip:'.Cache::get($client_id.'_ip'));
//        $output->writeln('current ip:'.$_SERVER['REMOTE_ADDR']);
//        if (Cache::get($client_id.'_ip') != $_SERVER['REMOTE_ADDR']){
//            $output->writeln('hacking :'.$_SERVER['REMOTE_ADDR']);
//            return;
//        }
        $message = base64_decode($message);
        $game = new Game();

//        $output->writeln(Session::get("user"));
        $output->writeln("--------------------------------------------------------");
        $output->writeln($message);
        $output->writeln("--------------------------------------------------------");

        $msg = json_decode($message, true);
        switch ($msg['type']) {
            //数据变更
            case "game_change":
                $rewards = new Rewards();
                //game
                $status = $msg['status'];

                if ($status == -1) {
                    $output->writeln("结算...");
                    $result = $rewards->settlement($msg['id'], $status, $msg['data']['winner']);
                    Events::report($client_id, $result);
                } else {
                    $output->writeln("切换到其他扣");
                    $result = $rewards->settlement($msg['id'], $status);
                    if ($result) {
                        Events::report($client_id, true);
                        $data = self::getReportContent($msg['id']);
                        Events::sendToAll(json_encode($data));
                    } else {
                        Events::report($client_id, false);
                    }
                }
                break;
            //请求数据
            case "report":
                $data = self::getReportContent($msg['id']);
                $output->writeln("info:" . json_encode($data));
                Events::sendToClient($client_id, json_encode($data));
                break;
            //客户端提交投注
            case "reward":
                //前端和后端字段不一致 在这里调整
                $data['uid'] = $msg['uid'];
                $data['kid'] = $msg['status'];
                $data['gid'] = $msg['no'];
                $data['reward'] = $msg['score'];
                $data['direction'] = $msg['who'];
                //
                $data['create_time'] = time();
                $data['kou'] = Cache::get('kou');

                //投注的状态和比赛状态不同步。撤销
                if (Game::get($data['gid'])['status'] != $data['kid']) {
                    self::report($client_id, false, "比赛状态变化，本次投注无效.");
                    return;
                }

                $rewards = new Rewards();
                $in = $rewards->insertReward($data);
                if ($in) {
                    self::report($client_id, true);
                    $user = User::get($data['uid']);
                    //通知用户刷新余额
                    $s['type'] = "score_update";
                    $s['data'] = $user['score'];
                    $s['his'] = $rewards->userGameReward($data['uid']);//用户当前的投注记录总额
                    //让客户端刷新余额
                    Events::sendToClient($client_id, json_encode($s));
                    self::noticeAllUpate($data['gid']);
                    //对后台发送消息
                    $chat['type'] = "chat";
                    //转移
                    $fff = $msg['who'] == 1 ? "红方" : "蓝方";
                    $ffff = $msg['status'] != 10 ? "个" : "分";
                    $fffff = $msg['status'] == 10 ? "开盆" : $msg['status'] . "扣";
                    $chat['content'] = $user['username'] . "在" . $fffff . "阶段投注" . $fff . ":" . $msg['score'] . $ffff;
                    $chat['from'] = 'reward';
                    Gateway::sendToUid('admin', base64_encode(json_encode($chat)));
                } else {
                    self::report($client_id, false, "余额不足");
                }
                break;
            //打赏草
            case "givesys":
                $system = System::getSystem();
                $notice = "";
                $type = 0;
                $user = User::get($msg['uid']);
                if ($user['score'] < $msg['score']) {
                    self::report($client_id, false, "余额不足");
                    break;
                }

                Db::startTrans();
                try {
                    switch ($msg['who']) {
                        case 1:
                            $system->setInc("redoperator", $msg['score']);
                            $notice = $msg['username'] . "打赏红草" . $msg['score'] . "朵鲜花";
                            $type = 1;
                            break;
                        case 2:
                            $system->setInc("blueoperator", $msg['score']);
                            $notice = $msg['username'] . "打赏蓝草" . $msg['score'] . "朵鲜花";
                            $type = 2;
                            break;
                        case 0:
                            $system->setInc("boardScore", $msg['score']);
                            $notice = $msg['username'] . "打赏监板" . $msg['score'] . "朵鲜花";
                            $type = 3;
                            break;
                    }
                    //扣除
                    $user->setDec('score', $msg['score']);
                    $his = new Userhis();
                    $his['gid'] = 0;
                    $his['uid'] = $msg['uid'];
                    $his['type'] = 3;
                    $his['data'] = $msg['score'];
                    $his['create_time'] = date("Y-m-d H:i:s");
                    $his['comment'] = $notice;
                    $his->save();
                    self::report($client_id, true, "打赏成功");
                    Db::commit();
                    //通知刷新余额
                    $s = [];
                    $s['type'] = "score_update";
                    $s['data'] = $user['score'];
                    Events::sendToClient($client_id, json_encode($s));
                    //对所有用户发送弹幕
                    $chat['type'] = "chat";
                    $chat['typeto'] = $type;
                    $chat['socre'] = $msg['score'];
                    $chat['content'] = $notice;
                    $chat['from'] = 'giveSys';
                    Events::sendToAll(json_encode($chat));
                } catch (Exception $e) {
                    Db::rollback();
                }

                break;
            case "result":
                //客户端通知发送结算信息
                $output->writeln("客户端请求结算信息");
                $output->writeln(print_r($msg, true));
                break;
            //用户聊天
            case "chat":
                Events::sendToAll($message);
                break;
            case "pong":
//                $output->writeln(print_r($_SERVER, true));//"user $client_id logout"
                if (!Cache::get($client_id . '_login', false)) {
                    Gateway::closeClient($client_id);
                }
                break;
        }
    }

    /**
     * 当用户断开连接时触发
     * @param int $client_id 连接id
     * @throws \Exception
     */
    public static function onClose($client_id)
    {
        // 向所有人发送
        Cache::clear($client_id . '_login');
        $output = new Output();
        $message4 = '{"type":"notice","data":"' . $client_id . ' has logout..."}';
        $output->writeln($message4);//"user $client_id logout"
        //Events::sendToAll($message4);
    }

    //组装游戏返回信息
    public static function getReportContent($id)
    {
        $game = new Game();
        $rewards = new Rewards();
        //查询所有表信息  返回
        $info = $rewards->getRewardsInfo($id);
        $m['data'] = $info;
        $m['type'] = "game_update";
        return $m;
    }

    //通知单独用户更新UI
    public static function report($client_id, $status, $msg = "")
    {
        $arr = ["type" => "status", "data" => $status, "msg" => $msg];
        Events::sendToClient($client_id, json_encode($arr));
    }

    //通知所有客户端更新比赛状态
    public static function noticeAllUpate($gid)
    {
        $m = self::getReportContent($gid);
        Events::sendToAll(json_encode($m));
    }


    //数据转换为base64

    public static function sendToClient($client, $data)
    {
        Gateway::sendToClient($client, base64_encode($data));
    }


    public static function sendToAll($data)
    {
        Gateway::sendToAll(base64_encode($data));
    }

    public static function sendToUid($uid,$data){
        Gateway::sendToUid($uid,base64_encode($data));
    }
}
